package utils

import (
	"encoding/json"
	"log"
	"reflect"
	"strings"
)

// 驼峰转蛇形
func ToSnakeString(s string) string {
	data := make([]byte, 0, len(s)*2)
	j := false
	num := len(s)
	for i := 0; i < num; i++ {
		d := s[i]
		if i > 0 && d >= 'A' && d <= 'Z' && j {
			data = append(data, '_')
		}
		if d != '_' {
			j = true
		}
		data = append(data, d)
	}
	return strings.ToLower(string(data[:]))

}

// 蛇形转驼峰
func ToCamelString(s string) string {
	data := make([]byte, 0, len(s))
	j := false
	k := false
	num := len(s) - 1
	for i := 0; i <= num; i++ {
		d := s[i]
		if k == false && d >= 'A' && d <= 'Z' {
			k = true
		}
		if d >= 'a' && d <= 'z' && (j || k == false) {
			d = d - 32
			j = false
			k = true
		}
		if k && d == '_' && num > i && s[i+1] >= 'a' && s[i+1] <= 'z' {
			j = true
			continue
		}
		data = append(data, d)
	}
	return string(data[:])
}

//递归的语义化分析
// todo  目前只做单层，以后支持多层
func GetStructCodeFromJson(s string, structName string) string {
	gencode := "type " + structName + " struct {\r\n"
	dat := map[string]interface{}{}
	e := json.Unmarshal([]byte(s), &dat)
	if nil != e {
		log.Print(e.Error())
		return ""
	}
	for k, v := range dat {
		log.Print(k, "  ", reflect.TypeOf(v).Kind().String())
		//如果是切片,切片类型
		if reflect.TypeOf(v).Kind() == reflect.Slice {
			gencode += "	" + ToCamelString(k) + "  " + reflect.TypeOf(v).Kind().String() + " `json:\"" + k + "\"` \r\n"
			log.Print(reflect.ValueOf(v).Slice(0, 0).Kind())
			//reflect.ValueOf(v).Slice(0,1)
			// todo  先暂时用interface代替
			continue
		}
		// 如果是字典
		if reflect.TypeOf(v).Kind() == reflect.Map {
			gencode += "	" + ToCamelString(k) + "  map[string]interface{} " + " `json:\"" + k + "\"` \r\n"

			for _, v := range reflect.ValueOf(v).MapKeys() {
				log.Print(v)
			}
			continue
		}
		gencode += "	" + ToCamelString(k) + "  " + reflect.TypeOf(v).Kind().String() + " `json:\"" + k + "\"` \r\n"
		// 基础类型直接加代码
	}
	gencode += "}"
	return gencode
}
